/*
 * pllist.cpp - multimedia player playlist GUI
 *
 * Copyright (C) 2010-2011 Serge Begger
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "pllist.h"
#include "ui_pllist.h"

pllist::pllist(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::pllist)
{
    ui->setupUi(this);

    initDbConnection();

    modelPlList = new QSqlRelationalTableModel(this);
    modelPlList->setTable("playlist");
    modelPlList->select();

    ui->pllistTableView->setModel(modelPlList);
    for (int i = 0; i < 10; ++i) {
        if (i == 1 || i == 5) continue;
        ui->pllistTableView->setColumnHidden(i,true);
    }
    ui->pllistTableView->setColumnWidth(1,580);
    ui->pllistTableView->setColumnWidth(5,110);
    ui->pllistTableView->verticalHeader()->setDefaultSectionSize(50);

    currTrack = 0;

    filesys = new fsys(this);
    connect(filesys, SIGNAL(destroyed()),this, SLOT(unHide()));
    connect(filesys, SIGNAL(addSource(QString)),this,SLOT(addFile(QString)));
    connect(filesys, SIGNAL(fsysHide()),this, SLOT(unHide()));
    connect(filesys, SIGNAL(initPlay()),this, SLOT(on_playButton_pressed()));
    filesys->hide();
}

pllist::~pllist()
{
    if (!db.isOpen()) {
        db.close();
    }
    delete ui;
}

void pllist::addPath(QString path)
{
    on_clearButton_pressed();
    filesys->addPath(path);
}

void pllist::on_playButton_pressed()
{
    emit stopPlay();
    int currRow = ui->pllistTableView->currentIndex().row();
    setCurrTrack(currRow+1);
    ui->pllistTableView->selectRow(currRow);
    emit startPlay();
}

void pllist::on_pushButPlUp_pressed()
{
    int currRow = ui->pllistTableView->currentIndex().row() - 1;
    if (currRow < 0)
        currRow = 0;
    ui->pllistTableView->selectRow(currRow);
}

void pllist::on_pushButPlDw_pressed()
{
    int currRow = ui->pllistTableView->currentIndex().row() + 1;
    if (currRow > modelPlList->rowCount())
        currRow = modelPlList->rowCount();
    ui->pllistTableView->selectRow(currRow);
}

void pllist::on_backButton_pressed()
{
    this->hide();
    emit pllistHide();
}

void pllist::on_addButton_pressed()
{
    ui->framePllist->hide();
    filesys->show();
}

void pllist::on_clearButton_pressed()
{
    emit stopPlay();
    if(modelPlList->rowCount()>0) {
        modelPlList->removeRows(0,modelPlList->rowCount());
        modelPlList->submitAll();
    }
    currTrack = 0;    
}

void pllist::on_delButton_pressed()
{
    if (modelPlList->rowCount() > 0) {
        modelPlList->removeRow(ui->pllistTableView->currentIndex().row());
        if (modelPlList->rowCount() == 0)
            currTrack = 0;
    }
}

void pllist::unHide()
{
    if (ui->framePllist->isHidden())
            ui->framePllist->show();
}

void pllist::addFile(QString filename)
{
    if (parseCue(filename)) return;
    int row = modelPlList->rowCount();
    modelPlList->insertRows(row, 1);
    modelPlList->setData(modelPlList->index(row, 0), filename);
    QString title ="";QString artist = "";QString album = "";QString length = "";
    int year = 0;
    if(!readTags(filename, title, artist, album, length, year)) {
        title = QFileInfo(filename).fileName();
    }
    modelPlList->setData(modelPlList->index(row, 1), artist + "-" + title);
    modelPlList->setData(modelPlList->index(row, 2), title);
    modelPlList->setData(modelPlList->index(row, 3), artist);
    modelPlList->setData(modelPlList->index(row, 4), album);
    modelPlList->setData(modelPlList->index(row, 5), length);
    modelPlList->setData(modelPlList->index(row, 6), year);
    modelPlList->setData(modelPlList->index(row, 7), false);
    modelPlList->setData(modelPlList->index(row, 8), 0);
    modelPlList->setData(modelPlList->index(row, 9), 0);
    modelPlList->submitAll();
    if (currTrack == 0)
        setCurrTrack(1);
}


bool pllist::parseCue(QString filename) {
    cueparser parser;
    if (parser.parse(filename)) {
        int max_track = parser.trackList.count();
        for (int i = 1; i < max_track; ++i) {
            track track = parser.trackList.at(i-1);
            int row = modelPlList->rowCount();
            modelPlList->insertRows(row, 1);
            modelPlList->setData(modelPlList->index(row, 0), filename);
            modelPlList->setData(modelPlList->index(row, 1), track.Artist + "-" + track.Title);
            modelPlList->setData(modelPlList->index(row, 2), track.Title);
            modelPlList->setData(modelPlList->index(row, 3), track.Artist);
            modelPlList->setData(modelPlList->index(row, 4), track.Album);
            modelPlList->setData(modelPlList->index(row, 5), lenghtToStr(track.Lenght/75));
            modelPlList->setData(modelPlList->index(row, 6), track.Year);
            modelPlList->setData(modelPlList->index(row, 7), true);
            modelPlList->setData(modelPlList->index(row, 8), track.Start);
            modelPlList->setData(modelPlList->index(row, 9), track.Lenght);            
            modelPlList->submitAll();
        }
        if (currTrack == 0)
            setCurrTrack(1);
        return true;
    }
    return false;
}


bool pllist::readTags(QString filename, QString &title, QString &artist,
                      QString &album, QString &length, int &year)
{
    TagLib::FileRef filerRef(filename.toLocal8Bit().constData());
    TagLib::Tag *tag;
    if(!filerRef.isNull() && filerRef.audioProperties()) {
        tag = filerRef.tag();
        if(tag) {
            if (!tag->isEmpty()) {
                title = tag->title().toCString(true);
                artist = tag->artist().toCString(true);
                album = tag->album().toCString(true);
                length = lenghtToStr(filerRef.audioProperties()->length());
                year = tag->year();
                return true;
            }
        }
    }
    return false;
}

QString pllist::lenghtToStr(qint64 lenght) {
    return QString("%1:%2").arg(QString::number(int(lenght/60)), lenght%60 < 10 ? QString("0%1").arg(QString::number(lenght%60)) : QString::number(lenght%60));
}

void pllist::setCurrTrack(int track)
{    
    int rows = modelPlList->rowCount();
    if (track > rows)
        track = 1;
    if (track <= 0 && rows != 0)
        track = rows;
    if (rows != 0)
    {
        ui->pllistTableView->setCurrentIndex(modelPlList->index(track-1,0));
        ui->pllistTableView->selectRow(track-1);
        currTrack = track;
    } else {
        currTrack = 0;
    }    
}

QString pllist::getCurrFileName()
{
    return getDbValue(0).toString();
}

QString pllist::getCurrTitle()
{
    QString title = getDbValue(2).toString();
    if (title.isEmpty())
        title = getDbValue(1).toString();
    return title;
}

QString pllist::getCurrArtist()
{
    return getDbValue(3).toString();
}

QString pllist::getCurrAlbum()
{
    return getDbValue(4).toString();
}

QString pllist::getCurrLength()
{
    return getDbValue(5).toString();
}

int pllist::getCurrYear()
{
    return getDbValue(6).toInt();
}

bool pllist::isFlacApe()
{
    return getDbValue(7).toBool();
}

int pllist::getStartTime()
{
    return getDbValue(8).toInt()/75;
}

int pllist::getLenTime()
{
    return getDbValue(9).toInt()/75;
}

QVariant pllist::getDbValue(int column) {
    QModelIndex index = modelPlList->index(currTrack-1,column);
    if (index.isValid())
        return modelPlList->data(index);
    else
        return "";
}

bool pllist::initDbConnection()
{
    if(QSqlDatabase::contains(QSqlDatabase::defaultConnection)) {
        db = QSqlDatabase::database();
    } else {
        db = QSqlDatabase::addDatabase("QSQLITE");
    }
    db.setDatabaseName(QDir::homePath() + "/qcarpc.db");
    if (!db.open()) {
        myMessage message(0);
        message.exec(0,"Cannot open qcarpc database!");
        return false;
    }
    QSqlQuery query;

    QStringList dbtables = db.tables(QSql::Tables);
    if (dbtables.contains( tr("playlist"), Qt::CaseInsensitive)) {
        if(db.record("playlist").count() < 9)
            query.exec("drop table playlist");
       else {
            return true;
       }
    }

    query.exec("create table playlist ( filename varchar(100),        "
                                     "fultitle varchar(200),        "
                                     "title varchar(200),         "
                                     "artist varchar(50),   "
                                     "album varchar(50),   "
                                     "length varchar(50),"
                                     "year int,"
                                     "flac_ape bool,"
                                     "cue_start long int,"
                                     "cue_lenght long int)");
    return true;
}
